home *** CD-ROM | disk | FTP | other *** search
- /* National Institute of Standards and Technology (NIST)
- /* National Computer System Laboratory (NCSL)
- /* Office Systems Engineering (OSE) Group
- /* ********************************************************************
- /* D I S C L A I M E R
- /* (March 8, 1989)
- /*
- /* There is no warranty for the NIST NCSL OSE SGML parser and/or the NIST
- /* NCSL OSE SGML parser validation suite. If the SGML parser and/or
- /* validation suite is modified by someone else and passed on, NIST wants
- /* the parser's recipients to know that what they have is not what NIST
- /* distributed, so that any problems introduced by others will not
- /* reflect on our reputation.
- /*
- /* Policies
- /*
- /* 1. Anyone may copy and distribute verbatim copies of the SGML source
- /* code as received in any medium.
- /*
- /* 2. Anyone may modify your copy or copies of SGML parser source code or
- /* any portion of it, and copy and distribute such modifications provided
- /* that all modifications are clearly associated with the entity that
- /* performs the modifications.
- /*
- /* NO WARRANTY
- /* ===========
- /*
- /* NIST PROVIDES ABSOLUTELY NO WARRANTY. THE SGML PARSER AND VALIDATION
- /* SUITE ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
- /* EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- /* THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
- /* WITH YOU. SHOULD THE SGML PARSER OR VALIDATION SUITE PROVE DEFECTIVE,
- /* YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
- /*
- /* IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL NIST BE LIABLE FOR
- /* DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
- /* INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
- /* INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
- /* BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
- /* FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
- /* NIST) THE PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF
- /* SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
- */
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #define COMMA -21
- #define AND -22
- #define OR -23
-
- #define NAMELEN 8
- #define NUMELTS 256
- #define NUMCOLS NUMELTS
- #define NUMROWS NUMELTS
- int errflag = 0;
- void saferead(), doread(), showmatrix(), heading(), setcell(), error(),
- analyze();
- /* ================================================================ */
-
- typedef struct {
- char Rcol[NUMCOLS];
- }ROW;
-
- typedef struct {
- int Smin;
- char Sname[8];
- int Snbr;
- }SYMBOL;
-
- typedef struct {
- int Dtoken;
- int Doi;
- int Dcontreq;
- } DTDREC;
- /* ================================================================ */
- SYMBOL symbol[NUMROWS];
- ROW Rrow[NUMROWS];
- unsigned char debug;
- /* ================================================================ */
- main(argc, argv)
- int argc;
- char *argv[];
- {
-
- int infile,numtokens,roottoken;
- register int j;
- char fname[128];
-
- infile = doinit(argc, argv, fname);
- saferead(infile, &numtokens, sizeof(numtokens));
- if (numtokens >= NUMROWS)
- error("too many tokens for closure tables");
- saferead(infile, &roottoken, sizeof(roottoken));
- /* read in all the symbols */
- for (j = 0; j < numtokens; j++){
- saferead(infile, &symbol[j], sizeof(SYMBOL));
- }
- for (j = 0; j < numtokens; j++)
- doread(infile, j, symbol);
- close(infile);
- showmatrix(numtokens);
- for (j = 0; ; j++){
- if (doclosure(numtokens) == 0)
- break;
- }
- showmatrix(numtokens);
- analyze(roottoken, numtokens, symbol);
- exit(0);
- }
- /* ================================================================ */
- void doread(infile, tokennbr, symbol)
- int infile, tokennbr;
- SYMBOL symbol[];
- {
- DTDREC tokeninfo;
- int andcount;
-
- saferead(infile, &tokeninfo, sizeof(tokeninfo)) ;
- switch(tokeninfo.Dtoken) {
- case COMMA:
- case OR:
- doread(infile, tokennbr, symbol);
- doread(infile, tokennbr, symbol);
- break;
- case AND:
- saferead(infile, &andcount, sizeof(andcount));
- while(andcount--)
- doread(infile, tokennbr, symbol);
- break;
- default:
- setcell(tokennbr, tokeninfo.Dtoken, symbol);
- }
- }
- /* ================================================================ */
- void setcell(row, col, symbol)
- int row;
- register int col;
- SYMBOL symbol[];
- {
- register char *temp = Rrow[row].Rcol;
- #ifdef JJJ
- if (col == 0) {
- strncpy(temp, symbol[row].Sname, NAMELEN);
- *(temp + NAMELEN) = 0;
- fprintf(stdout,"element '%s' contains root element as subelement\n",
- temp);
- return;
- }
- #endif
- if (col < 0)
- col = 0;
- *(temp + col) = 1;
- }
-
- /* ================================================================ */
- void showmatrix(count)
- register int count;
- {
- register int j, k;
- return;
- for (j = 0; j < count; j++){
- for (k = 0; k < count; k++)
- printf("[%02x]", Rrow[j].Rcol[k]);
- printf("\n");
- }
- printf("\n\n");
- }
-
- /* ================================================================ */
- int doclosure(count)
- int count;
- {
- int row;
- int chgdsomething = 0;
- register col, tempcol;
- for(row = 0; row < count; row++) {
- for(col = 1; col < count ;col++) {
- if (debug == 'Y')
- printf("<row = %d, col = %d>\n", row, col);
- if(Rrow[row].Rcol[col] == 1) {
- for(tempcol = 0; tempcol < count; tempcol++)
- {
- if (debug == 'Y')
- printf("Rrow[%d].Rcol[%d] = [%d]\n",
- col, tempcol, Rrow[col].Rcol[tempcol]);
- if(Rrow[col].Rcol[tempcol] == 1) {
- if (Rrow[row].Rcol[tempcol] != 1)
- chgdsomething++;
- Rrow[row].Rcol[tempcol] = 1;
- if (debug == 'Y')
- showmatrix(count);
- }
- }
- }
- }
- }
- return(chgdsomething);
- }
- /* ================================================================ */
- void saferead(file, buf, len)
- int file;
- unsigned char *buf;
- unsigned len;
- {
- int j;
- static int readcount = 0;
- readcount++;
- if ((j = read(file, buf, len)) != len) {
- error("read failure\n");
- j = j;
- }
- }
- /* ================================================================ */
- void error(msg)
- unsigned char *msg;
- {
- printf(msg);
- exit(1);
- }
- /* ================================================================ */
- doinit(argc, argv, fname)
- int argc;
- unsigned char *argv[];
- unsigned char *fname;
- {
- int infile;
- char temp[128];
-
- strcpy(fname, "dtdfile.sgm");
- if ((infile = open(fname, O_RDONLY)) == -1){
- sprintf(temp,"unable to open %s", fname);
- error(temp);
- }
- return(infile);
- }
- /* ================================================================ */
- void analyze(root, count, symbol)
- int root;
- register int count;
- SYMBOL symbol[];
- {
- register int j;
- char temp[128];
- ;
- for(j = 0; j < count; j++)
- if (Rrow[root].Rcol[j] != 1){
- if (j == root)
- continue;
- strncpy(temp, symbol[j].Sname, NAMELEN);
- *(temp + NAMELEN) = '\0';
- fprintf(stdout, "element %s may not have path to root element\n", temp);
- #ifdef JJJ
- printf("Press ENTER to continue\n");
- getchar();
- #endif
- errflag = 1;
- }
- for (j = 0; j < count; j++)
- if (Rrow[j].Rcol[0] != 1) {
- strncpy(temp, symbol[j].Sname, NAMELEN);
- *(temp + NAMELEN) = '\0';
- fprintf(stdout,"element %s may not have path to a terminal element\n",
- temp);
- #ifdef JJJ
- printf("Press ENTER to continue\n");
- getchar();
-
- #endif
- errflag = 1;
- }
- }
- /* ================================================================ */
-
- /*----------------------------------------------*/
- /* HEADING */
- /* Simply prints a informatory heading */
- /* when the document parser is invoked */
- /* describing the document name to be */
- /* parsed. */
- /*----------------------------------------------*/
-
- void heading()
- {
- printf("\n CLOSURE\n");
- printf(" Determine Closure of Elements\n");
- printf(" --------------------------------------------------\n");
- printf(" 10FEB87 Version 1.02\n");
- printf(" --------------------------------------------------\n\n");
- return;
- }
-